package com.foundersoftware.commons.organization;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;

import com.foundersoftware.commons.organization.dao.IOrganizationDAO;
import com.foundersoftware.commons.organization.dao.impl.BasicOrganizationManager;


/**
 * 
 *
 *
 * @author wuhongjun@routon.com
 * @version 1.0
 */
public final class OrganizationManagerFactory {

    /**
     * The property name that specifies the {@link com.foundersoftware.commons.organization.dao.IOrganizationDAO} class to use.
     */
    private static final String ORGANIZATION_STORE_TAG =
            "organization.organizationStore";

    private static final String ORGANIZATION_INTERFACE_TYPE_TAG =
            "organization.isRemote";


    private Properties props = null;
    private static Properties defaultProperties = new Properties();

    static {
        defaultProperties.put(ORGANIZATION_INTERFACE_TYPE_TAG, "true");
        defaultProperties.put(ORGANIZATION_STORE_TAG,
                "com.foundersoftware.commons.organization.dao.impl.RAMOrganizationStore");
    }


    public OrganizationManagerFactory() {
        props = defaultProperties;
    }

    public OrganizationManagerFactory(String fileName) throws
            OrganizationException {
        initialize(fileName);
    }

    public OrganizationManagerFactory(InputStream is) throws
            OrganizationException {
        initialize(is);

    }

    /**
     *

     *
     *
     * @return OrganizationManager
     */
    public OrganizationManager createOrganizationManager() {
        String orgStoreClassName = props.getProperty(ORGANIZATION_STORE_TAG);

        IOrganizationDAO orgStore = null;

        try {
            Class c = Class.forName(orgStoreClassName);

            Constructor constructor = c.getConstructor();
            orgStore = (IOrganizationDAO) constructor.newInstance();
        } catch (Exception ex) {
            throw new OrganizationException(ex);
        }

        if(Boolean.parseBoolean(props.getProperty(ORGANIZATION_INTERFACE_TYPE_TAG))) {

        	   return new BasicOrganizationManager(orgStore); 

        } else {

            return new BasicOrganizationManager(orgStore);
        }
    }



    public void initialize() throws OrganizationException {
        InputStream is = null;
        is = this.getClass().getResourceAsStream(
                "organization.properties");
        if (is == null) {
            throw new OrganizationException("Cannot find properties file :oraganization.porperties.") ;
        }

        initialize(is);

    }

    public void initialize(String fileName) throws OrganizationException {

        InputStream is = null;
        try {
            is = new FileInputStream(fileName);
        } catch (FileNotFoundException ex) {
            throw new OrganizationException("Cannot find the properties file :" +
                                            fileName, ex);
        }

        initialize(is);

    }

    public void initialize(InputStream is) throws OrganizationException {

        if (is == null) {
            throw new OrganizationException(
                    "Error loading property data from InputStream,because InputStream is null.");
        }
        Properties temProps = new Properties();

        try {
            temProps.load(is);
        } catch (IOException ex) {
            throw new OrganizationException(
                    "Error loading property data from InputStream ", ex);
        }

        initialize(temProps);

    }

    private void initialize(Properties props) {
        this.props.putAll(props);

    }
}
